﻿using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;

namespace UIModule
{
    [Serializable]
    public class InjectionObject
    {
        public string key;
        public Component value;
    }

    [Serializable]
    public class InjectionStruct
    {
        public string key;
        public string value;
    }

    [Serializable]
    public class DataInjection : MonoBehaviour
    {
        public List<InjectionObject> InjectionsComponent => _injections;
        public List<InjectionStruct> InjectionsStructs => _injectionsStructs;

        [SerializeField]
#if UNITY_EDITOR
        [OnValueChanged(nameof(AutoFill), true)]
#endif
        private List<InjectionObject> _injections = new List<InjectionObject>();

        [SerializeField] 
        private List<InjectionStruct> _injectionsStructs = new List<InjectionStruct>();
        private Dictionary<string, int> _dicInjection = new Dictionary<string, int>();
        private Dictionary<string, int> _dicInjectionStruct = new Dictionary<string, int>();

        private bool _init = false;

        public Component Get(string key)
        {
            Init();
            if (_dicInjection.TryGetValue(key, out int index))
            {
                return _injections[index].value;
            }

            Debug.LogError($"Get Component is {key} is not Exit");
            return null;
        }

        public T GetComponent<T>(string key) where T : Component
        {
            Init();
            if (_dicInjection.TryGetValue(key, out int index))
            {
                return _injections[index].value.GetComponent<T>();
            }

            Debug.LogError($"{key} Get Component is {typeof(T)} is not exist!");
            return null;
        }

        public string GetValue(string key)
        {
            Init();
            if (_dicInjectionStruct.TryGetValue(key, out int index))
            {
                return _injectionsStructs[index].value;
            }

            Debug.LogError($"GetValue is {key} is not Exit");
            return null;
        }

        private void Init()
        {
            if (_init)
            {
                return;
            }

            _dicInjection.Clear();
            _dicInjectionStruct.Clear();

            for (int i = 0; i < _injections.Count; i++)
            {
                _dicInjection[_injections[i].key] = i;
            }

            for (int i = 0; i < _injectionsStructs.Count; i++)
            {
                _dicInjectionStruct[_injectionsStructs[i].key] = i;
            }

            _init = true;
        }

        private void OnDestroy()
        {
            _init = false;
            _injections.Clear();
            _injectionsStructs.Clear();
            _dicInjection.Clear();
            _dicInjectionStruct.Clear();
        }


#if UNITY_EDITOR

        #region Editor

        private void AutoFill()
        {
            for (int i = 0; i < _injections.Count; i++)
            {
                if (string.IsNullOrEmpty(_injections[i].key))
                {
                    if (_injections[i].value != null)
                    {
                        _injections[i].key = _injections[i].value.name;
                    }
                }
            }
        }

        #endregion

#endif
    }
}